home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / obsolete / tiff_write.pro < prev    next >
Text File  |  1997-07-08  |  9KB  |  261 lines

  1. ; $Id: tiff_write.pro,v 1.2 1997/01/15 04:02:19 ali Exp $
  2. ;
  3. ; Copyright (c) 1991-1997. Research Systems, Inc. All rights reserved.
  4. ;    Unauthorized reproduction prohibited.
  5. ;+
  6. ; NAME:
  7. ;    TIFF_WRITE
  8. ;
  9. ; PURPOSE:
  10. ;    Write images in TIFF format.
  11. ;
  12. ; CATEGORY:
  13. ;    Input/output.
  14. ;
  15. ; CALLING SEQUENCE:
  16. ;    TIFF_WRITE, Filename, Array [, Orientation]
  17. ;
  18. ; INPUTS:
  19. ;     Filename:    A string containing the name of file to create. 
  20. ;
  21. ;    Array:    The image data to be written.  If not already a byte array,
  22. ;        it is made a byte array.  Array may be either an
  23. ;        [n, m] array for Grayscale or Palette classes, or
  24. ;        a [3, n, m] array for RGB full color, interleaved
  25. ;        by image.  If the PLANARCONFIG keyword (see below) is set
  26. ;        to 2 then the Array parameter is ignored (and may be
  27. ;        omitted). See PROCEDURE below for more information on
  28. ;        TIFF classes. 
  29. ;
  30. ; OPTIONAL INPUT PARAMETERS:
  31. ; Orientation:    This parameter should be 0 if the image is stored from bottom 
  32. ;        to top (the default).  For images stored from top to bottom, 
  33. ;        this parameter should be 1.  
  34. ;
  35. ;        WARNING:  Not all TIFF readers are capable of reversing the 
  36. ;        scan line order.  If in doubt, first convert the image
  37. ;        to top to bottom order (use the IDL REVERSE() function), and 
  38. ;        set Orientation to 1.
  39. ;
  40. ; OPTIONAL KEYWORD PARAMETERS:
  41. ; RED, GREEN, BLUE:
  42. ;        The color table vectors, scaled from 0 to 255 in the case of 
  43. ;        a Class P, Palette color image.  If, PlanarConfig is 2, these 
  44. ;        parameters must contain the 3 color component image parameters.
  45. ;
  46. ;        LONG:    If set, write the samples as 32 bit signed numbers.
  47. ; PLANARCONFIG:    Set this parameter to 2 if writing an RGB image that is 
  48. ;        contained in three separate images (color planes), specified
  49. ;        in the RED, GREEN, and BLUE parameters.  Otherwise, omit
  50. ;        this parameter (or set it to 1).
  51. ;
  52. ;        SHORT:    If set, write the samples as 16 bit signed numbers.
  53. ;        If neither SHORT or LONG are specified, write samples as
  54. ;        unsigned 8-bit numbers.
  55. ;    XRESOL:    The horizontal resolution, in pixels per inch.  The default
  56. ;        is 100.
  57. ;    YRESOL:    The vertical resolution, in pixels per inch.  The default
  58. ;        is 100.
  59. ;
  60. ; OUTPUTS:
  61. ;    No explicit inputs.
  62. ;
  63. ; COMMON BLOCKS:
  64. ;    TIFF_COM.  Only for internal use.
  65. ;
  66. ; SIDE EFFECTS:
  67. ;    A file is created and written.
  68. ;
  69. ; RESTRICTIONS:
  70. ;    This procedure writes images in a single strip, or 3 strips when 
  71. ;    PLANARCONFIG is set to 2.  This procedure may cause readers with 
  72. ;    memory limitations problems.
  73. ;
  74. ; PROCEDURE/EXAMPLES:
  75. ;    Four types of TIFF files can be written:
  76. ;
  77. ;    TIFF Class G, Grayscale.  Array contains the 8-bit image array.
  78. ;    A value of 0 is black, 255 is white.  The Red, Green, and Blue
  79. ;    keywords are omitted.  Example:
  80. ;        TIFF_WRITE, 'a.tiff', Array
  81. ;
  82. ;    TIFF Class P, Palette Color.  Array contains the 8-bit image array.  
  83. ;    The keyword parameters RED, GREEN, and BLUE contain the color tables, 
  84. ;    which can have up to 256 elements, scaled from 0 to 255.  Example:
  85. ;        TIFF_WRITE, 'a.tiff', Array, RED = r, GREEN = g, BLUE = b
  86. ;
  87. ;    TIFF Class R, RGB Full Color, color interleaved by pixel.
  88. ;    Array contains the byte data, and is dimensioned [3, cols, rows].
  89. ;    Example:
  90. ;        TIFF_WRITE, 'a.tiff', Array
  91. ;
  92. ;    TIFF Class R, RGB Full Color, color interleaved by image.
  93. ;    Input is three separate images, provided in the keyword
  94. ;    parameters RED, GREEN, and BLUE.  The input parameter "Array"
  95. ;    is ignored.  The keyword PLANARCONFIG must be set to 2 in this case.
  96. ;    Example:
  97. ;        TIFF_WRITE, 'a.tiff', RED = r, GREEN = g, BLUE = b, PLAN = 2
  98. ;
  99. ; MODIFICATION HISTORY:
  100. ;    DMS, Written for VMS in 1985.
  101. ;
  102. ;    DMS, April, 1991.  Rewrote and added class R and P images.
  103. ;    DJC, Nov, 1993.  Fixed doc header.
  104. ;    DMS, Aug, 1995.  Added support for 16 and 32 bit samples.
  105. ;-
  106. pro tiff_add_tag, lun, tag, value  ;Add a tag to the Image File Directory (IFD)
  107. common tiff_com, order, ifd, count
  108.  
  109. s = size(value)        ;Determine type from parameter
  110. typ = s[s[0]+1]        ;IDL type code
  111. tiff_typ = ([ 0, 1, 3, 4, 5, 0, 0, 2])[typ]  ;Tiff types vs IDL
  112. TypeLen = ([0, 1, 1, 2, 4, 8])[tiff_typ]
  113.  
  114. n = s[s[0]+2]        ; # of elements
  115. offset = count * 12 + 2    ; Offset into ifd
  116. ifd[offset] =   byte(fix(tag),0,2)    ;integer tag
  117. ifd[offset+2] = byte(tiff_typ, 0, 2)    ;data type
  118. ifd[offset+4] = byte(n,0,4)        ;count
  119. nbytes = n * TypeLen
  120.  
  121. if nbytes le 4 then begin    ;Simple case
  122.     ifd[offset+8] = byte(value,0,nbytes)
  123. endif else begin        ;Array, written to file
  124.     point_lun, -lun, pos   ;Get file posit
  125.     ifd[offset+8] = byte(pos, 0, 4)  ;Set IFD ^ pointer
  126.     if typ ne 4 then writeu, lun, value $    ;Write the data
  127.     else begin        ;Write floating
  128.         s = lonarr(n * 2)
  129.         s[indgen(n)*2] = value * 10000.  ;Arbritrary scale of 10000
  130.         s[indgen(n)*2+1] = 10000
  131.         writeu,lun, s
  132.     endelse
  133. endelse
  134. count = count + 1
  135. end
  136.  
  137.  
  138. pro tiff_write, filename, array, orientation, $
  139.     Red=red, Green=green, Blue=blue, Long=long, Short=short, $
  140.     PlanarConfig = PlanarConfig, Xresol = Xresol, Yresol = Yresol
  141. common tiff_com, order, ifd, count
  142.  
  143. on_error,2                      ;Return to caller if an error occurs
  144.  
  145. if n_elements(array) gt 0 then array = byte(array) ;Make sure it's byte
  146. s = size(array)
  147. if n_elements(PlanarConfig) le 0 then PlanarConfig = 1
  148.  
  149. color = 0            ;True if palette color with tables
  150.  
  151. if s[0] eq 3 then begin        ;True color image?
  152.     photo = 2
  153.     if s[1] ne 3 then message,'For true-color, image must be (3,n,m)'
  154.     cols = s[2]
  155.     rows = s[3]
  156.     samples = 3        ;3 samples / pixel
  157. endif else if PlanarConfig eq 2 then begin   ;RGB with separate sample planes
  158.     photo = 2
  159.     s = size(red)        ;Take image param from r,g,b
  160.     if s[0] ne 2 then message, 'Parameter must be 2D'
  161.     cols = s[1]
  162.     rows = s[2]
  163.     samples = 3
  164.     if (n_elements(red) ne n_elements(green)) or $
  165.         (n_elements(red) ne n_elements(blue)) then $
  166.         message,'Image components must have same size'
  167. endif else begin        ;Assume must be palette
  168.     if s[0] ne 2 then message, 'Parameter must be 2D'
  169.     cols = s[1]
  170.     rows = s[2]
  171.     samples = 1
  172.     if (n_elements(red) ne n_elements(green)) or $
  173.         (n_elements(red) ne n_elements(blue)) then $
  174.             message,'Color tables must have same size'
  175.     color = N_elements(red) GT 0
  176.     if color then photo = 3 else photo = 1
  177. endelse
  178.  
  179. if n_elements(orientation) eq 0 then orientation = 0
  180.  
  181. if (!version.os EQ 'MacOS') then begin
  182. openw, lun, filename, /BLOCK, /GET_LUN, MACTYPE = "TIFF"
  183. endif else begin
  184. openw, lun, filename, /BLOCK, /GET_LUN
  185. endelse
  186. header = bytarr(8)        ;The Tiff header
  187.  
  188. if keyword_set(long) then nbits = 32 $   ;Type of data for samples
  189. else if keyword_set(short) then nbits = 16 $
  190. else nbits = 8
  191. fcn_name = (['BYTE','FIX','', 'LONG'])[nbits/8-1]  ;Sample conversion function
  192.  
  193. tst = byte(1,0,2)        ;Which endian???
  194. if tst[0] eq 1 then header[0] = byte("II") $    ;Little endian
  195.    else header[0] = byte("MM")    ;Big endian
  196.  
  197. header[2] = byte(42,0,2)    ;Version = 42
  198.  
  199. writeu, lun, header
  200.  
  201. ifd = bytarr(512)        ;Image file directory
  202. count = 0            ;# of tags
  203.  
  204. tiff_add_tag, lun, 254, 0L        ;New Subfile type
  205. tiff_add_tag, lun, 256, long(cols)    ;Image width
  206. tiff_add_tag, lun, 257, long(rows)    ;Image height
  207.  
  208. tiff_add_tag, lun, 258, replicate(nbits,samples)  ;bit/sample
  209. tiff_add_tag, lun, 259, 1        ;No compression
  210. tiff_add_tag, lun, 262, photo    ;Photometric Interpretation
  211. nbytes = rows * cols * (nbits/8)    ;Bytes / plane
  212.  
  213. ; Write image data......
  214. point_lun, -lun, faddr        ;Get current file position
  215. if PlanarConfig eq 2 then begin ; write R,G,B in separate planes
  216.     tiff_add_tag, lun, 273, faddr + [0,1,2] * nbytes + 12  ;Strip offsets
  217.     writeu, lun, call_function(fcn_name, red)
  218.     writeu, lun, call_function(fcn_name, green)
  219.     writeu, lun, call_function(fcn_name, blue)
  220. endif else begin        ;Write image as one chunk
  221.     tiff_add_tag, lun,273, faddr  ;Strip offset
  222.     writeu, lun, call_function(fcn_name, array)
  223. endelse
  224.  
  225. tiff_add_tag, lun, 274, fix(4 - 3 * (orientation and 1)) ;Orientation  
  226. tiff_add_tag, lun, 277, samples    ;Samples / pixel
  227. tiff_add_tag, lun, 278, rows        ;Rows / strip
  228.  
  229. if PlanarConfig eq 2 then  t = replicate(nbytes, samples) $ ;Strip byte cnts
  230. else t = samples * nbytes
  231. tiff_add_tag, lun, 279,  t  ;Strip byte counts 
  232.  
  233. if n_elements(xresol) le 0 then xresol = 100.
  234. if n_elements(yresol) le 0 then yresol = 100.
  235. tiff_add_tag, lun, 282, float(xresol)        ;Xresolution
  236. tiff_add_tag, lun, 283, float(yresol)        ;... and Yresolution
  237. tiff_add_tag, lun, 284, PlanarConfig ;PlanarConfig
  238.  
  239. IF (photo EQ 3) THEN BEGIN    ;Add colormap?
  240.     rgb_array = intarr(768)    ;Make the color maps
  241.     rgb_array[0] = ishft(fix(red),8)  ;Scale up to 65K max
  242.     rgb_array[256] = ishft(fix(green), 8)
  243.     rgb_array[512] = ishft(fix(blue),8)
  244.     tiff_add_tag, lun, 320, rgb_array
  245.     ENDIF
  246.  
  247.  
  248. point_lun, -lun, faddr        ;Write IFD at and, get addr
  249. ifd[0] = byte(count,0,2)    ;Insert count
  250. writeu, lun, ifd[0: count*12+5] ;Write IFD followed by 4 zero bytes
  251.  
  252. point_lun, lun, 0        ;Rewind to header
  253. header[4] = byte(faddr,0,4)    ;Write ifd offset
  254. writeu, lun, header        ;And save it
  255.  
  256. free_lun,lun            ;Done
  257. end
  258.         
  259.  
  260.